﻿using System;
using System.Collections.Generic;
using YABE.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Mvc;
using YABE.Models;
using Rhino.Mocks;
using Rhino;

namespace YABETests
{
    /// <summary>
    ///This is a test class for PostsControllerTest and is intended
    ///to contain all PostsControllerTest Unit Tests
    ///</summary>
    [TestClass()]
    public class PostsControllerTest
    {
        protected MockRepository mockRepo;

        [TestMethod()]
        public void PostControllerShouldHave_ListMethod()
        {
            mockRepo = new MockRepository();
            IPostDL postDL = mockRepo.Stub<IPostDL>();
            Post newPost1 = mockRepo.Stub<Post>();
            newPost1.PostID = 1;
            Post newPost2 = mockRepo.Stub<Post>();
            newPost2.PostID = 2;
            List<Post> posts = new List<Post> { newPost1, newPost2 };
            using (mockRepo.Record())
            {
                SetupResult.For(postDL.GetPosts()).Return(posts);
            }
            PostsController postController = new PostsController(postDL);
            ActionResult result = postController.List();
            Assert.IsNotNull(result);
        }

        [TestMethod()]
        public void PostControllerShouldHave_ListYearMethod()
        {
            //arrange
            mockRepo = new MockRepository();
            IPostDL postDL = mockRepo.Stub<IPostDL>();
            SetupResult.For(postDL.GetPosts(1)).Return(new List<Post>());
            PostsController postsController = new PostsController(postDL);
            ActionResult result = postsController.ListYear(1);
            Assert.IsNotNull(result);
        }

        [TestMethod()]
        public void PostControllerShouldHave_ListMonthMethod()
        {
            mockRepo = new MockRepository();
            IPostDL postDL = mockRepo.Stub<IPostDL>();
            SetupResult.For(postDL.GetPosts(1, 1)).Return(new List<Post>());
            PostsController postsController = new PostsController(postDL);
            ActionResult result = postsController.ListMonth(1, 1);
            Assert.IsNotNull(result);
        }

        [TestMethod()]
        public void PostControllerShouldHave_ListDayMethod()
        {
            mockRepo = new MockRepository();
            IPostDL postDL = mockRepo.Stub<IPostDL>();
            SetupResult.For(postDL.GetPosts(1, 1, 1)).Return(new List<Post>());
            PostsController postsController = new PostsController(postDL);
            ActionResult result = postsController.ListDay(1, 1, 1);
            Assert.IsNotNull(result);
        }

        [TestMethod()]
        public void PostControllerShouldHave_SingleMethod()
        {
            mockRepo = new MockRepository();
            IPostDL postDL = mockRepo.Stub<IPostDL>();
            SetupResult.For(postDL.GetPost(1, 1, 1, "test")).Return(new Post());
            PostsController postsController = new PostsController(postDL);
            ActionResult result = postsController.Single(1, 1, 1, "test");
            Assert.IsNotNull(result);
        }

        [TestMethod()]
        public void PostControllerShouldHave_ListByTagMethod()
        {
            mockRepo = new MockRepository();
            IPostDL postDL = mockRepo.Stub<IPostDL>();
            SetupResult.For(postDL.GetPostsByTag("test")).Return(new List<Post>());
            PostsController postsController = new PostsController(postDL);
            ActionResult result = postsController.ListByTag("test");
            Assert.IsNotNull(result);
        }

        [TestMethod]
        public void PostControllerShouldHave_IndexMethod()
        {
            mockRepo = new MockRepository();
            IPostDL postDL = mockRepo.Stub<IPostDL>();
            Post newPost1 = mockRepo.Stub<Post>();
            newPost1.PostID = 1;
            Post newPost2 = mockRepo.Stub<Post>();
            newPost2.PostID = 2;
            List<Post> posts = new List<Post> { newPost1, newPost2 };
            using (mockRepo.Record())
            {
                SetupResult.For(postDL.GetPosts()).Return(posts);
            }
            PostsController postsController = new PostsController(postDL);
            ActionResult result = postsController.Index();
            Assert.IsNotNull(result);
        }

        [TestMethod()]
        public void PostControllerShouldHave_AboutMethod()
        {
            PostsController postController = new PostsController();
            ActionResult result = postController.About();
            Assert.IsNotNull(result);
        }

        [TestMethod()]
        public void PostControllerShouldHave_AddMethod()
        {
            PostsController postsController = new PostsController();
            ActionResult result = postsController.Add();
            Assert.IsNotNull(result);
        }

        /// <summary>
        ///A test for List and its view
        ///</summary>
        [TestMethod()]
        public void ListActionShouldReturnListView()
        {
            //arrange 
            string expected = "List";
            mockRepo = new MockRepository();
            IPostDL postDL = mockRepo.Stub<IPostDL>();
            PostsController target = new PostsController(postDL); 
            List<Post>posts = new List<Post>();
            using (mockRepo.Record())
            {
                SetupResult.For(postDL.GetPosts()).Return(posts);
            }
            //act
             var actual = target.List() as ViewResult;

                //assert
                Assert.IsNotNull(actual.ViewName);
                Assert.AreEqual(expected, actual.ViewName);
            
        }

        /// <summary>
        ///A test for List for its view data type
        ///</summary>
        [TestMethod()]
        public void ListActionShouldSendPostTypeDataToView()
        {
            mockRepo = new MockRepository();
            IPostDL postDL = mockRepo.Stub<IPostDL>();
            PostsController target = new PostsController(postDL);
            List<Post> posts = new List<Post>();
            using (mockRepo.Record())
            {
                SetupResult.For(postDL.GetPosts()).Return(posts);
            }

            Type expected = typeof(List<YABE.Models.Post>);
            var runAction = target.List();
            Assert.IsInstanceOfType(target.ViewData.Model, expected);
        }

        /// <summary>
        ///A test for List reversing posts
        ///</summary>
        [TestMethod()]
        public void ListActionShouldSendPostsInReverseOrder()
        {
            //arrange
            mockRepo = new MockRepository();
            IPostDL postDL = mockRepo.Stub<IPostDL>();
            Post newPost1 = mockRepo.Stub<Post>();
            newPost1.PostID = 1;
            Post newPost2 = mockRepo.Stub<Post>();
            newPost2.PostID = 2;
            List<Post> posts = new List<Post> { newPost1, newPost2 };
            using (mockRepo.Record())
            {
                SetupResult.For(postDL.GetPosts()).Return(posts);
            }
            PostsController target = new PostsController(postDL);
            
            //act
            var viewResult = target.List() as ViewResult;
            var result = (List<Post>)viewResult.ViewData.Model;
           
            //assert
            Assert.AreEqual(newPost2.PostID, result[0].PostID);
            Assert.AreEqual(newPost1.PostID, result[1].PostID);
        }
        
       
    }
}
